#include "rgb.h"
#include "rgb_cfg.h"
#include "string.h"


rgb_para_t rgb_para;

void Rgb_Init(void)
{
    Rgb_Port_Init();
    memset(&rgb_para, 0, sizeof(rgb_para_t));
}

// sta设置的状态, 灯条ON开,  OFF关闭, CHANGE颜色变换(此部分可根据项目需求随意更改)
void Pwm_Sta_Set(rgb_state_t sta)
{
    unsigned char i = 0;
    rgb_para.sta = sta;
    if (OFF == sta) {
        rgb_para.rgb_flag = FALSE;
        rgb_para.color_sta = CLS;
        Rgb_Color_Handle(rgb_para.color_sta);
    }
    else if (ON == sta) {
        rgb_para.rgb_flag = TRUE;
        rgb_para.color_sta = RED;
        Rgb_Color_Handle(rgb_para.color_sta);
    } else if (CHANGE == sta) {
        if (!rgb_para.rgb_flag)
            return ;
        rgb_para.color_sta++;
        Rgb_Color_Handle(rgb_para.color_sta);
    }
}

/**
 * @description: 设备处理
 *               放入1ms定时器中断中处理，如果需要放慢速度，开启FADE_MUL_ENABLE宏
 */
void Rgb_Isr_Process(void)
{
    static rgb_u16_t cnt = 0, marq_cnt = 0; //cnt时基计数  ,marq跑马灯时基计数

    #if RGB_PWM
        rgb_u8_t i;
        #if FADECOLOR
            for (i = 0; i < DEV_NUM; i++) {
                if (FADE_OFF == rgb_para.dev[i].fade_sta)
                    return;
                else if (FADE_IN == rgb_para.dev[i].fade_sta) {
                    if (rgb_para.dev[i].pwm_cur_cnt != rgb_para.dev[i].fade_cnt) {
                        #ifdef FADE_MUL_ENABLE
                            if (FADE_IN_MUL_CNT <= ++rgb_para.dev[i].mul_cnt) {
                                rgb_para.dev[i].mul_cnt = 0;
                                rgb_para.dev[i].pwm_cur_cnt += FADE_MIN_CNT;
                            }
                        #else
                            rgb_para.dev[i].pwm_cur_cnt += FADE_MIN_CNT;
                        #endif
                        if (MAX_FADE_CNT <= rgb_para.dev[i].pwm_cur_cnt) {
                            rgb_para.dev[i].pwm_cur_cnt = MAX_FADE_CNT;
                            rgb_para.dev[i].mul_cnt = 0;
                            rgb_para.dev[i].fade_sta = FADE_OFF;
                        }
                        Rgb_Opt_Port(i, rgb_para.dev[i].pwm_cur_cnt);
                    }
                } else if (FADE_OUT == rgb_para.dev[i].fade_sta) {
                    if (rgb_para.dev[i].pwm_cur_cnt != rgb_para.dev[i].fade_cnt) {
                        if (FADE_MIN_CNT <= rgb_para.dev[i].pwm_cur_cnt) {
                            #ifdef FADE_MUL_ENABLE
                                if (FADE_IN_MUL_CNT <= ++rgb_para.dev[i].mul_cnt) {
                                    rgb_para.dev[i].mul_cnt = 0;
                                    rgb_para.dev[i].pwm_cur_cnt -= FADE_MIN_CNT;
                                }
                            #else
                                rgb_para.dev[i].pwm_cur_cnt -= FADE_MIN_CNT;
                            #endif
                            if (MIN_FADE_CNT == rgb_para.dev[i].pwm_cur_cnt) {
                                rgb_para.dev[i].pwm_cur_cnt = 0;
                                rgb_para.dev[i].mul_cnt = 0;
                                rgb_para.dev[i].fade_sta = FADE_OFF;
                            }
                        } else {
                            rgb_para.dev[i].pwm_cur_cnt = 0;
                            rgb_para.dev[i].fade_sta = FADE_OFF;
                        }
                        Rgb_Opt_Port(i, rgb_para.dev[i].pwm_cur_cnt);
                    }
                }
            }
        #endif
        #if (GRADCOLOR || GRAD_MARQ)
            if (++cnt > GRAD_MUL_CNT) {
                cnt = 0;
                #if MARQ_COLOR
                    if (rgb_para.marq_flag)
                        return ;
                #endif
                if (rgb_para.duty_flag == 0) {
                    rgb_para.dev[DEV_R_LED].duty.cnt++;
                    rgb_para.dev[DEV_G_LED].duty.cnt++;
                    rgb_para.dev[DEV_B_LED].duty.cnt++;
                }
                if (rgb_para.duty_flag == 1 && (rgb_para.dev[DEV_R_LED].duty.cnt)) {
                    rgb_para.dev[DEV_R_LED].duty.cnt--;
                    rgb_para.dev[DEV_G_LED].duty.cnt--;
                    rgb_para.dev[DEV_B_LED].duty.cnt--;
                }
            }

            if (rgb_para.dev[DEV_R_LED].duty.cnt == MAX_FADE_CNT) {   //MAX_FADE_CNT
                rgb_para.duty_flag = TRUE;
            }
            if (rgb_para.dev[DEV_R_LED].duty.cnt == MIN_FADE_CNT) {
                    static rgb_u16_t num = 0;
                    if (++num >= GRAD_MUL_CNT * 25) {               //关灯时增加一点延时
                        num = 0;
                        rgb_para.duty_flag = FALSE;
                        #if GRAD_MARQ
                            rgb_para.marq_sta++;
                            if (rgb_para.marq_sta > WHITE) {
                                rgb_para.marq_sta = RED;
                            }
                        #endif
                    }
            }

            for (i = 0; i < DEV_NUM; i++) {
                if(!rgb_para.dev[i].flag.sta) {
                    Rgb_Opt_Port(i, 0);
                } else {
                    Rgb_Opt_Port(i, rgb_para.dev[i].duty.cnt);
                }
            }
        #endif
        #if (!GRADCOLOR && !FADECOLOR)
            for (i = 0; i < DEV_NUM; i++) {
                if (rgb_para.dev[i].flag.sta) {
                    Rgb_Opt_Port(i, rgb_para.dev[i].fade_cnt);
                } else {
                    Rgb_Opt_Port(i, 0);
                }
            }


        #endif

        #if MARQ_COLOR
           if (rgb_para.marq_flag) {
               Rgb_Color_Handle(rgb_para.marq_sta);
                if (MARQ_TIMEOUT <= marq_cnt++) {
                    marq_cnt = 0;
                    rgb_para.marq_sta++;
                }
                if (rgb_para.marq_sta > WHITE) {
                    rgb_para.marq_sta = RED;
                }
           }
        #elif GRAD_MARQ
            if (rgb_para.marq_flag) {
                Rgb_Color_Handle(rgb_para.marq_sta);
            }
        #endif

        #if LIGHT_GRADE
            if (rgb_para.press_flag) {
                static rgb_u8_t num = 0;
                if (rgb_para.light_cnt >= 255) {
                    rgb_para.duty_flag = FALSE;

                }
                if (rgb_para.light_cnt == 0) {
                    rgb_para.duty_flag = TRUE;
                }
                if (++num >= 12) {
                    num = 0;
                    if (rgb_para.duty_flag) {
                        rgb_para.light_cnt++;
                    } else {
                        rgb_para.light_cnt--;
                    }
                }

            }
        #endif
    #else
        #if (CHANGE_COLOR)
            #if (GRADCOLOR || GRAD_MARQ)
				if (++cnt > GRAD_MUL_CNT) {
					cnt = 0;
					if (rgb_para.duty_flag == 0 && (rgb_para.dev[DEV_R_LED].duty.cnt != MAX_FADE_CNT)) {
						rgb_para.dev[DEV_R_LED].duty.cnt++;
						rgb_para.dev[DEV_G_LED].duty.cnt++;
						rgb_para.dev[DEV_B_LED].duty.cnt++;
					}
					if ((rgb_para.duty_flag == 1) && (rgb_para.dev[DEV_R_LED].duty.cnt)) {
						rgb_para.dev[DEV_R_LED].duty.cnt--;
						rgb_para.dev[DEV_G_LED].duty.cnt--;
						rgb_para.dev[DEV_B_LED].duty.cnt--;
					}
				}
                if (rgb_para.dev[DEV_R_LED].duty.cnt == MAX_FADE_CNT) {   //MAX_FADE_CNT
                    rgb_para.duty_flag = TRUE;
                }
                if (rgb_para.dev[DEV_R_LED].duty.cnt == MIN_FADE_CNT) {
                    rgb_para.duty_flag = FALSE;
                }
            #endif
            #if MARQ_COLOR
                if (rgb_para.marq_flag) {
                    Change_Process(rgb_para.marq_sta);
                    if (MARQ_TIMEOUT <= marq_cnt++) {
                        marq_cnt = 0;
                        rgb_para.marq_sta++;
                    }
                    if (rgb_para.marq_sta > WHITE) {
                        rgb_para.marq_sta = RED;
                    }
                }
            #elif GRAD_MARQ
                if (rgb_para.marq_flag) {
                    Rgb_Color_Handle(rgb_para.marq_sta);
                    if (rgb_para.dev[DEV_R_LED].duty.cnt == MAX_FADE_CNT) {
                        if (GRAD_MUL_CNT <= marq_cnt++) {                      //呼吸灯开启倍数功能时需要加入延时,否则会出现颜色状态连续加
                            rgb_para.marq_sta++;
                            marq_cnt = 0;
                        }
                    }
                    if (rgb_para.marq_sta > WHITE) {
                        rgb_para.marq_sta = RED;
                    }
                }
            #endif
        #endif
    #endif
}

void Rgb_Color_Handle(rgb_color_t color)
{
    rgb_u8_t i = 0;
    #if RGB_PWM
        #if (CHANGE_COLOR)                                                  //PWM状态下,呼吸灯和淡出淡出,常规七彩通用
            for (i = 0; i < DEV_NUM; i++) {
                rgb_para.dev[i].flag.sta = FALSE;
            }
            // rgb_para.dev[DEV_R_LED].flag.sta = FALSE;
            // rgb_para.dev[DEV_G_LED].flag.sta = FALSE;
            // rgb_para.dev[DEV_B_LED].flag.sta = FALSE;
            if (color == RED) {
                rgb_para.dev[DEV_R_LED].fade_cnt = MAX_FADE_CNT;            //红
                rgb_para.dev[DEV_B_LED].fade_cnt = MIN_FADE_CNT;            //蓝
                rgb_para.dev[DEV_G_LED].fade_cnt = MIN_FADE_CNT;            //绿
                rgb_para.dev[DEV_R_LED].flag.sta = TRUE;                    //红色的状态
            } else if (color == GREEN) {
                rgb_para.dev[DEV_R_LED].fade_cnt = MIN_FADE_CNT;            //红
                rgb_para.dev[DEV_B_LED].fade_cnt = MIN_FADE_CNT;            //蓝
                rgb_para.dev[DEV_G_LED].fade_cnt = MAX_FADE_CNT;            //绿
                rgb_para.dev[DEV_G_LED].flag.sta = TRUE;
            } else if (color == BLUE) {
                rgb_para.dev[DEV_R_LED].fade_cnt = MIN_FADE_CNT;            //红
                rgb_para.dev[DEV_B_LED].fade_cnt = MAX_FADE_CNT;            //蓝
                rgb_para.dev[DEV_G_LED].fade_cnt = MIN_FADE_CNT;            //绿
                rgb_para.dev[DEV_B_LED].flag.sta = TRUE;
            } else if (color == YELLOW) {
                rgb_para.dev[DEV_R_LED].fade_cnt = MAX_FADE_CNT;            //红
                rgb_para.dev[DEV_B_LED].fade_cnt = MIN_FADE_CNT;            //蓝
                rgb_para.dev[DEV_G_LED].fade_cnt = MAX_FADE_CNT;            //绿
                rgb_para.dev[DEV_R_LED].flag.sta = TRUE;
                rgb_para.dev[DEV_G_LED].flag.sta = TRUE;
            } else if (color == CYAN) {
                rgb_para.dev[DEV_R_LED].fade_cnt = MIN_FADE_CNT;            //红
                rgb_para.dev[DEV_B_LED].fade_cnt = MAX_FADE_CNT;            //蓝
                rgb_para.dev[DEV_G_LED].fade_cnt = MAX_FADE_CNT;            //绿
                rgb_para.dev[DEV_B_LED].flag.sta = TRUE;
                rgb_para.dev[DEV_G_LED].flag.sta = TRUE;
            } else if (color == PURPLE) {
                rgb_para.dev[DEV_R_LED].fade_cnt = MAX_FADE_CNT;            //红
                rgb_para.dev[DEV_B_LED].fade_cnt = MAX_FADE_CNT;            //蓝
                rgb_para.dev[DEV_G_LED].fade_cnt = MIN_FADE_CNT;            //绿
                rgb_para.dev[DEV_R_LED].flag.sta = TRUE;
                rgb_para.dev[DEV_B_LED].flag.sta = TRUE;
            } else if (color == WHITE) {
                rgb_para.dev[DEV_R_LED].fade_cnt = MAX_FADE_CNT;            //红
                rgb_para.dev[DEV_B_LED].fade_cnt = MAX_FADE_CNT;            //蓝
                rgb_para.dev[DEV_G_LED].fade_cnt = MAX_FADE_CNT;            //绿
                rgb_para.dev[DEV_R_LED].flag.sta = TRUE;
                rgb_para.dev[DEV_B_LED].flag.sta = TRUE;
                rgb_para.dev[DEV_G_LED].flag.sta = TRUE;
            }
            #if (MARQ_COLOR || GRAD_MARQ)
                else if (color == MARQ) {
                    rgb_para.marq_flag = TRUE;
                    rgb_para.marq_sta = RED;                                    //跳过marq_sta为0的状态
                }
            #endif
             else {
                rgb_para.dev[DEV_R_LED].fade_cnt = MIN_FADE_CNT;            //红
                rgb_para.dev[DEV_B_LED].fade_cnt = MIN_FADE_CNT;            //蓝
                rgb_para.dev[DEV_G_LED].fade_cnt = MIN_FADE_CNT;            //绿
                rgb_para.color_sta = CLS;
                rgb_para.marq_sta = CLS;
                rgb_para.marq_flag = FALSE;
            }
            #if FADECOLOR
                /**
                 * @description: 在RGB颜色切换时，不做淡出，直接从40开始淡入，防止有白色闪光问题
                 *               如果从0开始淡入会有明显的从熄灭到亮的过程，看着很不舒服
                 */
                for (i = 0; i < DEV_NUM; i++) {
                    rgb_para.dev[i].pwm_cur_cnt = 40;
                    if (rgb_para.dev[i].pwm_cur_cnt > rgb_para.dev[i].fade_cnt) {
                        rgb_para.dev[i].fade_sta = FADE_OUT;
                    } else if (rgb_para.dev[i].pwm_cur_cnt < rgb_para.dev[i].fade_cnt) {
                        rgb_para.dev[i].fade_sta = FADE_IN;
                    } else {
                        rgb_para.dev[i].fade_sta = FADE_OFF;
                    }
                }
            #endif
        #endif
    #else
        #if (CHANGE_COLOR)
            for (i = 0; i < DEV_NUM; i++) {
                rgb_para.dev[i].flag.duty = FALSE;
                #if FADECOLOR
                    if (!rgb_para.marq_flag) {
                        rgb_para.duty_flag = TRUE;
                        rgb_para.dev[i].duty.cnt = (MAX_FADE_CNT - 25);            //淡入淡出的初值,如果初值是MAX_FADE_CNT会有一个从灭到亮的过程
                    }
                #endif
            }
            switch (color) {
                case RED : {
                    rgb_para.dev[DEV_R_LED].flag.duty = TRUE;
                    RGB_B = FALSE;
                    RGB_G = FALSE;
                    break;
                }
                case GREEN : {
                    rgb_para.dev[DEV_G_LED].flag.duty = TRUE;
                    RGB_R = FALSE;
                    RGB_B = FALSE;
                    break;
                }
                case BLUE : {
                    rgb_para.dev[DEV_B_LED].flag.duty = TRUE;
                    RGB_R = FALSE;
                    RGB_G = FALSE;
                    break;
                }
                case YELLOW : {
                    rgb_para.dev[DEV_G_LED].flag.duty = TRUE;
                    rgb_para.dev[DEV_R_LED].flag.duty = TRUE;
                    RGB_B = FALSE;
                    break;
                }
                case CYAN : {
                    rgb_para.dev[DEV_B_LED].flag.duty = TRUE;
                    rgb_para.dev[DEV_G_LED].flag.duty = TRUE;
                    RGB_R = FALSE;
                    break;
                }
                case PURPLE : {
                    rgb_para.dev[DEV_R_LED].flag.duty = TRUE;
                    rgb_para.dev[DEV_B_LED].flag.duty = TRUE;
                    RGB_G = FALSE;
                    break;
                }
                case WHITE : {
                    rgb_para.dev[DEV_R_LED].flag.duty = TRUE;
                    rgb_para.dev[DEV_G_LED].flag.duty = TRUE;
                    rgb_para.dev[DEV_B_LED].flag.duty = TRUE;
                    break;
                }
                #if (MARQ_COLOR || GRAD_MARQ)
                    case MARQ : {
                        rgb_para.marq_flag = TRUE;
                        rgb_para.marq_sta = RED;                                    //跳过marq_sta为0的状态
                        break;
                    }
                #endif
                default : {
                    #if (FADECOLOR && !GRAD_MARQ && !MARQ_COLOR)                    //跑马灯开启时,关闭无淡出
                        rgb_para.duty_flag = FALSE;
                        rgb_para.marq_sta = CLS;
                        rgb_para.color_sta = CLS;
                        rgb_para.marq_flag = FALSE;
                        rgb_para.dev[DEV_R_LED].flag.duty = TRUE;
                        rgb_para.dev[DEV_G_LED].flag.duty = TRUE;
                        rgb_para.dev[DEV_B_LED].flag.duty = TRUE;
                        rgb_para.dev[DEV_R_LED].duty.cnt = (MAX_FADE_CNT / 2);
                        rgb_para.dev[DEV_B_LED].duty.cnt = (MAX_FADE_CNT / 2);      //淡出时从一半亮度开始淡出
                        rgb_para.dev[DEV_G_LED].duty.cnt = (MAX_FADE_CNT / 2);
                    #else
                        RGB_R = FALSE;
                        RGB_B = FALSE;
                        RGB_G = FALSE;
                        rgb_para.color_sta = CLS;
                        rgb_para.marq_sta = CLS;
                        rgb_para.marq_flag = FALSE;
                        rgb_para.rgb_flag = FALSE;
                    #endif
                        break;
                }
            }
        #else                                                                        //常规七彩灯处理
            Change_Process(color);
        #endif

    #endif
}

void Change_Process(rgb_color_t color)
{
    #if ((RGB_PWM == FALSE) && (CHANGE_COLOR))
        switch (color) {
            case RED : {
                RGB_R = TRUE;
                RGB_B = FALSE;
                RGB_G = FALSE;
                break;
            }
            case GREEN : {
                RGB_R = FALSE;
                RGB_B = FALSE;
                RGB_G = TRUE;
                break;
            }
            case BLUE : {
                RGB_R = FALSE;
                RGB_B = TRUE;
                RGB_G = FALSE;
                break;
            }
            case YELLOW : {
                RGB_R = TRUE;
                RGB_B = FALSE;
                RGB_G = TRUE;
                break;
            }
            case CYAN : {
                RGB_R = FALSE;
                RGB_B = TRUE;
                RGB_G = TRUE;
                break;
            }
            case PURPLE : {
                RGB_R = TRUE;
                RGB_B = TRUE;
                RGB_G = FALSE;
                break;
            }
            case WHITE : {
                RGB_R = TRUE;
                RGB_B = TRUE;
                RGB_G = TRUE;
                break;
            }
            #if (MARQ_COLOR || GRAD_MARQ)
                case MARQ : {
                    rgb_para.marq_flag = TRUE;
                    rgb_para.marq_sta = RED;        //常规模式时,跑马灯时会继续调用此函数,当color为MARQ开启跑马灯后,color的值会变为0,执行default,marq_sta要跳过0
                    break;
                }
            #endif

            default : {
                RGB_R = FALSE;
                RGB_B = FALSE;
                RGB_G = FALSE;
                rgb_para.color_sta = CLS;
                rgb_para.marq_sta = CLS;
                rgb_para.marq_flag = FALSE;
                break;
            }
        }

    #endif
}

void Rgb_Process(void)
{
	GPIO_WriteBit(RGB_R_PORT, RGB_R_PIN, RGB_R);
	GPIO_WriteBit(RGB_G_PORT, RGB_G_PIN, RGB_G);
	GPIO_WriteBit(RGB_B_PORT, RGB_B_PIN, RGB_B);
    #if (RGB_PWM == FALSE)
        #if (GRADCOLOR || FADECOLOR)
            rgb_u8_t i;
            static rgb_u16_t cnt;
                cnt++;
                if (cnt > (MAX_FADE_CNT - 15)) {                        //呼吸灯灭时增加一点延时
                    cnt = 0;
                }
                if (rgb_para.dev[DEV_G_LED].flag.duty) {
                    if (cnt >= rgb_para.dev[DEV_G_LED].duty.cnt) {
                        RGB_G = TRUE;
                    } else {
                        RGB_G = FALSE;
                    }
                }
                if (rgb_para.dev[DEV_B_LED].flag.duty) {
                    if (cnt >= rgb_para.dev[DEV_B_LED].duty.cnt) {
                        RGB_B = TRUE;
                    } else {
                        RGB_B = FALSE;
                    }
                }
                if (rgb_para.dev[DEV_R_LED].flag.duty) {
                    if (cnt >= rgb_para.dev[DEV_R_LED].duty.cnt) {
                        RGB_R = TRUE;
                    } else {
                        RGB_R = FALSE;
                    }
                }
        #endif

    #endif
}

#if 0
void Scan_Rgb(rgb_u8_t v, color_rgb_t rgb)
{
    if (v == 0) {
        Rgb_Opt_Port(RGB_R, 0);
        Rgb_Opt_Port(RGB_G, 0);
        Rgb_Opt_Port(RGB_B, 0);
    } else {
        color_rgb.r = (unsigned char)(color_rgb.color << 16);
        color_rgb.g = (unsigned char)(color_rgb.color << 8);
        color_rgb.b = (unsigned char)(color_rgb.color);
        Rgb_Opt_Port(RGB_R, color_rgb.r);
        Rgb_Opt_Port(RGB_G, color_rgb.g);
        Rgb_Opt_Port(RGB_B, color_rgb.b);
    }
}
#endif

